package controller

import (
	"context"
	"fmt"
	"net/http"
	"time"

	tableComm "gitee.com/klein-x/biz/model/mysql/table/comm"
	tableUser "gitee.com/klein-x/biz/model/mysql/table/user"
	"gitee.com/klein-x/biz/module/db/mysql"
	"gitee.com/klein-x/biz/module/wx"
)

func WxPrePay(ctx context.Context, uid string, orderId string) (string, error) {
	// 查询order
	order, err := tableComm.OrderGetByKey(orderId)
	if err != nil {
		return "", err
	}
	if order == nil {
		return "", fmt.Errorf("无效的订单id")
	}
	if order.TotalAmount == 0 { // 如果总金额是0  则不通过支付系统,本地直接结算
		goods, err := tableComm.GoodsGetByKey(order.GoodsID)
		if err != nil {
			return "", err
		}
		if goods == nil {
			return "", fmt.Errorf("商品不存在或已下架")
		}
		asset, err := tableUser.AssetsGetByUserAndChapterID(uid, goods.ChapterID)
		if err != nil {
			return "", err
		}
		if asset != nil {
			// 判断字段是否已经过期， 如果已经过期 就更改开始时间和结束时间，如果没有就只更新结束时间
			timestamp := time.Now().Unix()
			if asset.EndTime < uint64(timestamp) { //已经过期
				asset.StartTime = uint64(timestamp)
				asset.EndTime = asset.StartTime + goods.Duration
			} else {
				asset.EndTime = asset.EndTime + goods.Duration
			}
		} else {
			timestamp := time.Now().Unix()
			asset = tableUser.AssetsDefine(uid, goods.ChapterID)
			asset.StartTime = uint64(timestamp)
			asset.EndTime = asset.StartTime + goods.Duration
		}
		order.Status = "3"
		tx := mysql.BeginTran()

		if err := tableUser.AssetsUpadte(asset); err != nil {
			tx.Rollback()
			return "", err
		}
		if err := tableComm.OrderUpdate(order); err != nil {
			tx.Rollback()
			return "", err
		}
		tx.Commit()
	} else {
		// 发起预支付得到预支付id
		// wx.MakePrePayId()

		// 启动15分定时关闭预支付线程

		// 更新订单状态
		order.Status = "1"
		if err := tableComm.OrderUpdate(order); err != nil {
			return "", err
		}
	}
	return order.ID, nil
}

func WxPayResult(ctx context.Context, uid string, PrePayId string) (string, error) {
	// 停止预支付定时关闭线程
	// 线程主动查询支付结果
	// 线程主动查询订单状态
	// 定时时间时间45秒，超时关闭预支付订单

	order, err := tableComm.OrderGetByKey(PrePayId)
	if err != nil {
		return "", err
	}
	if order == nil {
		return "", fmt.Errorf("无效的预支付id")
	}
	// 订单状态，未支付0,待支付1,已支付2、已完成3
	if order.Status == "2" || order.Status == "3" {
		return PrePayId, nil
	}

	if order.Status == "0" {
		return "", fmt.Errorf("未发起支付请求或支付请求已超时")
	}

	goods, err := tableComm.GoodsGetByKey(order.GoodsID)
	if err != nil {
		return "", err
	}
	if goods == nil {
		return "", fmt.Errorf("商品不存在或已下架")
	}

	asset, err := tableUser.AssetsGetByUserAndChapterID(uid, goods.ChapterID)
	if err != nil {
		return "", err
	}
	if asset != nil {
		// 判断字段是否已经过期， 如果已经过期 就更改开始时间和结束时间，如果没有就只更新结束时间
		timestamp := time.Now().Unix()
		if asset.EndTime < uint64(timestamp) { //已经过期
			asset.StartTime = uint64(timestamp)
			asset.EndTime = asset.StartTime + goods.Duration
		} else {
			asset.EndTime = asset.EndTime + goods.Duration
		}
	} else {
		timestamp := time.Now().Unix()
		asset = tableUser.AssetsDefine(uid, goods.ChapterID)
		asset.StartTime = uint64(timestamp)
		asset.EndTime = asset.StartTime + goods.Duration
	}
	order.Status = "3"
	tx := mysql.BeginTran()

	if err := tableUser.AssetsUpadte(asset); err != nil {
		tx.Rollback()
		return "", err
	}
	if err := tableComm.OrderUpdate(order); err != nil {
		tx.Rollback()
		return "", err
	}
	tx.Commit()
	return PrePayId, nil
}

// 微信Notify 回调处理
func WxPayNotify(ctx context.Context, req *http.Request) (int, error) {
	var notifyMsg map[string]interface{} // 用于存放回调通知内容
	// 调用微信支付api解析应答报文
	notifyRequest, err := wx.HandleNotification(ctx, req, &notifyMsg)
	if err != nil {
		return http.StatusBadRequest, fmt.Errorf("微信通知回调签名验证失败,%v", err)
	}

	// 根据报文结果处理逻辑
	switch notifyRequest.EventType {
	case "TRANSACTION.SUCCESS":
		// 支付成功通知
		fmt.Printf("支付成功: %+v\n", notifyMsg)
	case "TRANSACTION.REFUND":
		// 退款通知
		fmt.Printf("退款成功: %+v\n", notifyMsg)
	default:
		// 其他类型通知
		fmt.Printf("收到通知: %+v\n", notifyMsg)
	}
	return http.StatusOK, nil
}

// 微信PrePay 错误处理
// if err != nil {
// 	return nil, fmt.Errorf("调用微信支付api失败: %v", err)
// }
// hlog.Infof("调用微信预支付status=%d resp=%+v\n", result.Response.StatusCode, resp)

// // 从响应中提取prepay_id
// prepayID := resp.PrepayId
// if prepayID == nil || *prepayID == "" {
// 	return nil, fmt.Errorf("未获取到prepay_id")
// }
// return prepayID, nil
